using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace RandomRat {

	/// <summary>
	/// A control for editing options (Num in set, Suc-tol, EveryOther-Tol, AdvPatern, etc).
	/// </summary>
	public class OptionsControl : System.Windows.Forms.UserControl {

		public event ChangeEventHandler Change;

		private ArrayList advancedPatternRules;


		#region WINVARS

		private System.Windows.Forms.GroupBox groupBox1;
		private NumberBox txtEveryOtherTol;
		private NumberBox txtSuccessionToler;
		private NumberBox txtSlots;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.CheckBox chkEveryOtherTol;
		private System.Windows.Forms.CheckBox chkSuccessionTol;
		private System.Windows.Forms.Button butViewAdvPattTol;
		private System.Windows.Forms.CheckBox chkAdvPatTol;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.CheckBox chkForceEqualTypes;
		private System.Windows.Forms.ErrorProvider errorProvider1;
		private System.ComponentModel.Container components = null;

		#endregion

		public OptionsControl() {
			InitializeComponent();

			advancedPatternRules = new ArrayList(10);
			label2.Text = "";
		}


		#region Change event and button validation

		private void OnChange() {
			validateControl();

			if (Change != null) {
				Change(this, new EventArgs());
			}
		}

		private void validateControl() {
			txtSuccessionToler.Enabled = chkSuccessionTol.Checked;
			txtEveryOtherTol.Enabled = chkEveryOtherTol.Checked;
			butViewAdvPattTol.Enabled = chkAdvPatTol.Checked;
			label2.Enabled = chkAdvPatTol.Checked;

			validateAdvPatternIndicator();
		}

		private void validateAdvPatternIndicator() {
			if (advancedPatternRules != null && advancedPatternRules.Count > 0) {
				label2.Text = advancedPatternRules.Count.ToString();
			} else {
				label2.Text = "";
			}
		}

		#endregion




		#region Public interface functions
		
		public void ClearSettings() {
			// Revert to blank strarting state
			txtSlots.Text = "";
			txtSuccessionToler.Text = "";
			txtEveryOtherTol.Text = "";
			chkSuccessionTol.Checked = true;
			chkEveryOtherTol.Checked = true;
			chkAdvPatTol.Checked = false;
			chkForceEqualTypes.Checked = false;			
			
			advancedPatternRules.Clear();
            OnChange();
		}



		#region INPUT / OUTPUT

		// Implmented
		public void FillFormState(ref CriteriaFormState formState) {
			// Slots
			formState.Slots = txtSlots.Text;

			// SuccessionTol
			formState.checkedSuccessionTol = chkSuccessionTol.Checked;
			formState.SuccessionTol = txtSuccessionToler.Text;

			// EveryOtherTol
			formState.checkedEveryOtherTol = chkEveryOtherTol.Checked;
			formState.EveryOtherTol = txtEveryOtherTol.Text;

			// Advanced pattern rules
			formState.advancedPatternRules = advancedPatternRules;
			formState.checkedPatternRules = chkAdvPatTol.Checked;

			// Force equal types
			formState.checkedForceEqualTypes = chkForceEqualTypes.Checked;
		}

		public void FillSetArguments(ref SetArguments setArgs) {
			// Slots
			setArgs.Slots = -1;
			if (txtSlots.Text != "") 
				setArgs.Slots = int.Parse(txtSlots.Text);

			// SuccessionTol
			if (chkSuccessionTol.Checked && txtSuccessionToler.Text != "") {
				setArgs.SuccessionTol = int.Parse(txtSuccessionToler.Text);
			} else {
				setArgs.SuccessionTol = -1;
			}

			// Merge every other and advancedPatternRules
			ArrayList tempPatternRules = new ArrayList();
			if (chkEveryOtherTol.Checked && txtEveryOtherTol.Text != "") {
				tempPatternRules.Add(new int[2] {2, int.Parse(txtEveryOtherTol.Text)});
			}

			if (advancedPatternRules.Count > 0 && chkAdvPatTol.Checked) {
				tempPatternRules.AddRange(advancedPatternRules);
			}

			// convert to int[][]
			setArgs.patternRules = (int[][])tempPatternRules.ToArray(typeof(int[]));

				// Set forced equal types
				setArgs.forceEqualTypes = chkForceEqualTypes.Checked;
		}

		
		
		public void LoadSettings(CriteriaFormState formState) {
			// Slots
			txtSlots.Text = formState.Slots;

			// SuccessionTol
			chkSuccessionTol.Checked = formState.checkedSuccessionTol;
			txtSuccessionToler.Text = formState.SuccessionTol;

			// EveryOtherTol
			chkEveryOtherTol.Checked = formState.checkedEveryOtherTol;
			txtEveryOtherTol.Text = formState.EveryOtherTol;

			// Advanced pattern rules
			advancedPatternRules = formState.advancedPatternRules;
			chkAdvPatTol.Checked = formState.checkedPatternRules;

			// Force equal types
			chkForceEqualTypes.Checked = formState.checkedForceEqualTypes;

			// Update viwers
			OnChange();
		}
		
		// Not implemneted
		public void LoadSettings(SetArguments setArgs) {

		}


		#endregion


		#region ERROR Handeling

		const string error1 = "Please provide a value";
		const string error5 = "The 'number in set' must be grater than zero.";
		const string error2 = "The 'number in set' must be a multiple of the number of types";

		const string error3 = "Succession tolerance must be grater than zero.";
		const string error4 = "Every-other tolerance must be grater than zero.";
		


		/// <summary>
		/// Returns whether control conforms to SetArguments
		/// </summary>
		/// <param name="showError">Show user input errors via error provider</param>
		/// <returns></returns>
		public bool IsInputValid(bool showError, int numOfTypes) {
			// First kill any leading zeros
			txtSlots.ValidateAsInt();
			txtSuccessionToler.ValidateAsInt();
			txtEveryOtherTol.ValidateAsInt();
			
			bool valid = true;

			ClearErrors();

			// Slots: if blank, error.  if not multiple of types, error.
			if (txtSlots.Text == "") {
				valid = false;
				if(showError) errorProvider1.SetError(txtSlots, error1);
			
			} else if (txtSlots.Text == "0") {
				valid = false;
				if(showError) errorProvider1.SetError(txtSlots, error5);

			} else if (numOfTypes > 0 && chkForceEqualTypes.Checked &&
				       int.Parse(txtSlots.Text) % numOfTypes != 0) {

				valid = false;
				if(showError) errorProvider1.SetError(txtSlots, error2);
			}

			// Unckeck every-other if blank, error if "0"
			if (chkSuccessionTol.Checked && txtSuccessionToler.Text == "") {
				chkSuccessionTol.Checked = false;
			}
			if (chkSuccessionTol.Checked && txtSuccessionToler.Text == "0") {
				valid = false;
				if(showError) errorProvider1.SetError(txtSuccessionToler, error3);
			}

			// Uncheck every-other if blank, error if "0"
			if (chkEveryOtherTol.Checked && txtEveryOtherTol.Text == "") {
				chkEveryOtherTol.Checked = false;
			}
			if (chkEveryOtherTol.Checked && txtEveryOtherTol.Text == "0") {
				valid = false;
				if(showError) errorProvider1.SetError(txtEveryOtherTol, error4);
			}

			return valid;
		}

		public void ClearErrors() {
			errorProvider1.SetError(txtSlots, "");
			errorProvider1.SetError(txtSuccessionToler, "");
			errorProvider1.SetError(txtEveryOtherTol, "");
		}


		#endregion

		#endregion




		// Shows the advansed pattern tol diolog
		private void showAdvPatternTolDialog() {
			PatternSettings psForm = new PatternSettings(advancedPatternRules);
			psForm.ShowDialog();
			psForm.Dispose();
			
			OnChange();
		}

		
		private void butViewAdvPattTol_Click(object sender, System.EventArgs e) {
			showAdvPatternTolDialog();
		}

		
		
		private void someControlChanged(object sender, System.EventArgs e) {
			OnChange();
		}




		#region UTIL
		protected override void Dispose( bool disposing ) {
			if( disposing ) {
				if(components != null) {
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}
		#region Component Designer generated code
		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.groupBox1 = new System.Windows.Forms.GroupBox();
			this.txtEveryOtherTol = new RandomRat.NumberBox();
			this.txtSuccessionToler = new RandomRat.NumberBox();
			this.txtSlots = new RandomRat.NumberBox();
			this.label1 = new System.Windows.Forms.Label();
			this.chkEveryOtherTol = new System.Windows.Forms.CheckBox();
			this.chkSuccessionTol = new System.Windows.Forms.CheckBox();
			this.butViewAdvPattTol = new System.Windows.Forms.Button();
			this.chkAdvPatTol = new System.Windows.Forms.CheckBox();
			this.label2 = new System.Windows.Forms.Label();
			this.chkForceEqualTypes = new System.Windows.Forms.CheckBox();
			this.errorProvider1 = new System.Windows.Forms.ErrorProvider();
			this.groupBox1.SuspendLayout();
			this.SuspendLayout();
			// 
			// groupBox1
			// 
			this.groupBox1.Controls.AddRange(new System.Windows.Forms.Control[] {
																					this.txtEveryOtherTol,
																					this.txtSuccessionToler,
																					this.txtSlots,
																					this.label1,
																					this.chkEveryOtherTol,
																					this.chkSuccessionTol,
																					this.butViewAdvPattTol,
																					this.chkAdvPatTol,
																					this.label2,
																					this.chkForceEqualTypes});
			this.groupBox1.Location = new System.Drawing.Point(1, -1);
			this.groupBox1.Name = "groupBox1";
			this.groupBox1.Size = new System.Drawing.Size(254, 160);
			this.groupBox1.TabIndex = 23;
			this.groupBox1.TabStop = false;
			this.groupBox1.Text = "Options";
			// 
			// txtEveryOtherTol
			// 
			this.txtEveryOtherTol.Location = new System.Drawing.Point(184, 76);
			this.txtEveryOtherTol.MaxLength = 6;
			this.txtEveryOtherTol.Name = "txtEveryOtherTol";
			this.txtEveryOtherTol.Size = new System.Drawing.Size(48, 20);
			this.txtEveryOtherTol.TabIndex = 3;
			this.txtEveryOtherTol.Text = "";
			this.txtEveryOtherTol.TextChanged += new System.EventHandler(this.someControlChanged);
			// 
			// txtSuccessionToler
			// 
			this.txtSuccessionToler.Location = new System.Drawing.Point(184, 50);
			this.txtSuccessionToler.MaxLength = 6;
			this.txtSuccessionToler.Name = "txtSuccessionToler";
			this.txtSuccessionToler.Size = new System.Drawing.Size(48, 20);
			this.txtSuccessionToler.TabIndex = 2;
			this.txtSuccessionToler.Text = "";
			this.txtSuccessionToler.TextChanged += new System.EventHandler(this.someControlChanged);
			// 
			// txtSlots
			// 
			this.txtSlots.Location = new System.Drawing.Point(184, 24);
			this.txtSlots.MaxLength = 6;
			this.txtSlots.Name = "txtSlots";
			this.txtSlots.Size = new System.Drawing.Size(48, 20);
			this.txtSlots.TabIndex = 1;
			this.txtSlots.Text = "";
			this.txtSlots.TextChanged += new System.EventHandler(this.someControlChanged);
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(32, 26);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(88, 16);
			this.label1.TabIndex = 9;
			this.label1.Text = "Number in set:";
			// 
			// chkEveryOtherTol
			// 
			this.chkEveryOtherTol.Checked = true;
			this.chkEveryOtherTol.CheckState = System.Windows.Forms.CheckState.Checked;
			this.chkEveryOtherTol.Location = new System.Drawing.Point(16, 78);
			this.chkEveryOtherTol.Name = "chkEveryOtherTol";
			this.chkEveryOtherTol.Size = new System.Drawing.Size(136, 16);
			this.chkEveryOtherTol.TabIndex = 6;
			this.chkEveryOtherTol.Text = "Every-other tolerance:";
			this.chkEveryOtherTol.CheckedChanged += new System.EventHandler(this.someControlChanged);
			// 
			// chkSuccessionTol
			// 
			this.chkSuccessionTol.Checked = true;
			this.chkSuccessionTol.CheckState = System.Windows.Forms.CheckState.Checked;
			this.chkSuccessionTol.Location = new System.Drawing.Point(16, 52);
			this.chkSuccessionTol.Name = "chkSuccessionTol";
			this.chkSuccessionTol.Size = new System.Drawing.Size(136, 16);
			this.chkSuccessionTol.TabIndex = 5;
			this.chkSuccessionTol.Text = "Succession tolerance:";
			this.chkSuccessionTol.CheckedChanged += new System.EventHandler(this.someControlChanged);
			// 
			// butViewAdvPattTol
			// 
			this.butViewAdvPattTol.Enabled = false;
			this.butViewAdvPattTol.Location = new System.Drawing.Point(184, 104);
			this.butViewAdvPattTol.Name = "butViewAdvPattTol";
			this.butViewAdvPattTol.Size = new System.Drawing.Size(48, 20);
			this.butViewAdvPattTol.TabIndex = 4;
			this.butViewAdvPattTol.Text = "View...";
			this.butViewAdvPattTol.Click += new System.EventHandler(this.butViewAdvPattTol_Click);
			// 
			// chkAdvPatTol
			// 
			this.chkAdvPatTol.Location = new System.Drawing.Point(16, 106);
			this.chkAdvPatTol.Name = "chkAdvPatTol";
			this.chkAdvPatTol.Size = new System.Drawing.Size(168, 16);
			this.chkAdvPatTol.TabIndex = 7;
			this.chkAdvPatTol.Text = "Advanced pattern tolerance:";
			this.chkAdvPatTol.CheckedChanged += new System.EventHandler(this.someControlChanged);
			// 
			// label2
			// 
			this.label2.Enabled = false;
			this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label2.Location = new System.Drawing.Point(232, 107);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(18, 16);
			this.label2.TabIndex = 39;
			this.label2.Text = "2";
			this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			// 
			// chkForceEqualTypes
			// 
			this.chkForceEqualTypes.Location = new System.Drawing.Point(16, 132);
			this.chkForceEqualTypes.Name = "chkForceEqualTypes";
			this.chkForceEqualTypes.Size = new System.Drawing.Size(120, 16);
			this.chkForceEqualTypes.TabIndex = 40;
			this.chkForceEqualTypes.Text = "Force equal types";
			this.chkForceEqualTypes.CheckedChanged += new System.EventHandler(this.someControlChanged);
			// 
			// errorProvider1
			// 
			this.errorProvider1.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
			// 
			// OptionsControl
			// 
			this.Controls.AddRange(new System.Windows.Forms.Control[] {
																		  this.groupBox1});
			this.Name = "OptionsControl";
			this.Size = new System.Drawing.Size(256, 160);
			this.groupBox1.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion



		
		#endregion



	}
}
